<?php
declare (strict_types = 1);

namespace app\command;

use think\App;
use think\console\Command;
use think\console\Input;
use think\console\Output;

class Crontab extends Command
{
    /**
     * @var string 指令
    */
    private $cmd = '';

    /**
     * @var array 参数
    */
    private $params = [];

    /**
     * @var string 执行逻辑的类名
    */
    private $class = '';

    /**
     * @var string 执行逻辑的方法名
     */
    private $method = '';


    protected function configure()
    {
        // 指令配置
        $this->setName('crontab')
            ->addArgument('cmd')
            ->addArgument('params')
            ->setDescription('主定时任务,负责分配子定时任务');
    }

    protected function initialize(Input $input, Output $output)  {
        //获取指令
        $command = $input->getArgument('cmd');
        $params = $input->getArgument('params');
        if (empty($command)) {
            abort(400, '定时任务命令不能为空');
        }
        //解析指令   eg:order/batchPull
        $list = explode('/', $command);
        if (count($list) < 2) {
            abort(400, '定时任务命令不合法');
        }
        [$this->class, $this->method] = $list;
        $argv = [];
        //如果有参数,将参数解析成数组 k1=v1,k2=v2   ['k1'=>v1,'k2'=>v2]
        if (!empty($params)) {
            $params = str_replace('，', ',', $params);
            $list = explode(',', $params);
            foreach ($list as $v) {
                $_list = explode('=', $v);
                if (count($_list) < 2) {
                    continue;
                }
                [$_k, $_v] = $_list;
                $argv[$_k] = $_v;
            }
        }
        $this->params = $argv;
    }

    protected function execute(Input $input, Output $output)
    {
        if (!empty($this->params['crontab_code'])) {
            //设置当前进程名称
            cli_set_process_title("crontab {$this->params['crontab_code']}");
        }
        $this->dispatch($this->class, $this->method, $this->params);
    }

    /**
     * 分配子定时器
    */
    private function dispatch(string $class, string $method, array $params) : void {
        $class = 'app\\logic\\crontab\\' . ucfirst($class);
        $this->app->invokeMethod([$class, $method], [$params]);
    }
}
